function slideUp( gameElement, i, j )
{
    g_gameField[i-1][j] = g_gameField[i][j];

    var stopPosition = parseInt( gameElement.top ) - 82;
    var interval = setInterval( function()
    {
        gameElement.top = ( parseInt( gameElement.top ) - 1 ) + 'px';
        if ( parseInt( gameElement.top ) <= stopPosition )
        {
            clearInterval( interval );
        }
    }, 10 );
}

function slideLeft( gameElement, i, j )
{
    g_gameField[i][j-1] = g_gameField[i][j];

    var stopPosition = parseInt( gameElement.left ) - 82;
    var interval = setInterval( function(){
        gameElement.left = ( parseInt( gameElement.left ) - 1 ) + 'px';;
        if ( parseInt( gameElement.left ) <= stopPosition )
        {
            clearInterval( interval );
        }
    }, 10 );
}

function slideDown( gameElement, i, j )
{
    g_gameField[i+1][j] = g_gameField[i][j];
    
    var stopPosition = parseInt( gameElement.top ) + 82;
    var interval = setInterval( function(){
        gameElement.top = ( parseInt( gameElement.top ) + 1 ) + 'px';;
        if ( parseInt( gameElement.top ) >= stopPosition )
        {
            clearInterval( interval );
        }
    }, 10 );
}

function slideRight( gameElement, i, j )
{
    g_gameField[i][j+1] = g_gameField[i][j];

    var stopPosition = parseInt( gameElement.left ) + 82;
    var interval = setInterval( function(){
        gameElement.left = ( parseInt( gameElement.left ) + 1 ) + 'px';
        if ( parseInt( gameElement.left ) >= stopPosition )
        {
            clearInterval( interval );
        } 
    }, 10 );
}

function checkWinner()
{
    for ( var i = 0; i < 3; ++i )
    {
        for ( var j = 0; j < 3; ++j )
        {
            if ( g_gameField[i][j] != g_winPosition[i][j] )
            {
                return false;
            }
        }
    }
    return true;
}

function makeStepAndCheckWin()
{
    var steps = document.getElementById( 'steps' );
    steps.textContent = parseInt( steps.textContent ) + 1;
    g_isMoving = false;
    if ( checkWinner() )
    {
        document.getElementById( 'complete' ).style.display = 'block';
        document.getElementById( 'you_win' ).style.display  = 'block';
    }
}

function tryMove( i, j )
{
    var gameElement = document.getElementById( g_gameField[i][j] ).style;
    
    var canMoveDown  = ( i != 2 ) && ( g_gameField[i+1][j] == '0' );
    var canMoveUp    = ( i )      && ( g_gameField[i-1][j] == '0' );
    var canMoveRight = ( j != 2 ) && ( g_gameField[i][j+1] == '0' );
    var canMoveLeft  = ( j )      && ( g_gameField[i][j-1] == '0' );
    
    g_isMoving = true;
    if ( canMoveDown )
    {
        slideDown( gameElement, i, j );
    }
    else if ( canMoveUp )
    {
        slideUp( gameElement, i, j );
    }
    else if ( canMoveRight )
    {
        slideRight( gameElement, i, j );
    }
    else if ( canMoveLeft )
    {
        slideLeft( gameElement, i, j );
    }
    else
    {
        g_isMoving = false;
        return false; 
    }
    setTimeout( makeStepAndCheckWin, 900 );
    g_gameField[i][j] = '0'; 
    return false; 
}

function checkWay()
{
    if ( g_isMoving )
    {
        return false;
    }
    for ( var i = 0; i < 3; ++i )
    {
        for ( var j = 0; j < 3; ++j )
        {
            if ( g_gameField[i][j] == this.id )
            {
                return tryMove( i, j );
            }
        }
    }
}

function initializeField()
{
    for ( var i = 0; i < 3; ++i )
    {
        for ( var j = 0; j < 3; ++j )
        {
            if ( g_gameField[i][j] != '0' )
            {
                var element = document.getElementById( g_gameField[i][j] );
                element.style.top  = i * 82 + 'px';
                element.style.left = j * 82 + 'px';
                element.onclick = checkWay;
            }
        }
    }
}

function getEmptySlotRow( gameSequence )
{
    for ( var i = 0; i < 9; ++i )
    {
        if ( gameSequence[i] == '0' )
    	{
            return Math.ceil( ( 1 + i ) / 3 );
        }
    }
}

function getElementSequence()
{
    var gameSequence = new Array(9), k = 0;
    for ( var i = 0; i < 3; ++i )
    {
        for ( var j = 0; j < 3; ++j )
        {
            gameSequence[k] = g_gameField[i][j];
            k++;
        }
    }
    return gameSequence;
}

function calcPossibleInversions( gameSequence )
{
    var inversions = 0;
    for ( var i = 0; i < 9; ++i )
    {
        if ( gameSequence[i] != '0' )
    	{
            for ( var j = 0; j < i; ++j )
            {
                if ( gameSequence[j] > gameSequence[i] )
                {
                    ++inversions;
                }
            }
    	}
    }
    return inversions;
}

function isCombinationSolved()
{
    if ( checkWinner() )
    {
        return false;
    }
    var gameSequence = getElementSequence();
    var inversions   = calcPossibleInversions( gameSequence );
    var emptySlotRow = getEmptySlotRow( gameSequence );
    
    if ( emptySlotRow == 2 )
    {
        return false;
    }
    inversions += emptySlotRow;
    if ( inversions & 1 )
    {
        return true;
    }
    return false;    
}

function shuffleGameField()
{
    do
    {
        g_gameField = shuffle( g_gameField );
    } while ( !isCombinationSolved() );
    initializeField();
}

function playGame()
{
    var completeImage = document.getElementById( 'complete' ).style;
    if ( completeImage.display != 'none' )
    {
        shuffleGameField();
        completeImage.display = 'none';
        document.getElementById( 'you_win' ).style.display = 'none';
        document.getElementById( 'steps' ).textContent = '0';
    }
}

function newGame()
{
    document.getElementById( 'you_win' ).style.display = 'none';
    document.getElementById( 'complete' ).style.display = 'block';
}

var g_isMoving = false;

var g_gameField   = [['pic1', 'pic2', 'pic3'],
                     ['pic4', 'pic5', 'pic6'],
                     ['pic7', 'pic8', '0'   ]];
                     
var g_winPosition = [['pic1', 'pic2', 'pic3'],
                     ['pic4', 'pic5', 'pic6'],
                     ['pic7', 'pic8', '0'   ]];
                     
function gameStart()
{
    var playButton    = document.getElementById( 'play' );
    var newGameButton = document.getElementById( 'new_game' );

    playButton.onclick    = playGame;
    newGameButton.onclick = newGame;
}